/**
 * Copyright (c) 2009 Cerner Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Cerner Corporation - initial API and implementation
 */
package com.cerner.system.rest.resource.organizer;

import java.util.Set;

/**
 * API to navigate hierarchical URIs, access and modify the representation of
 * its associated resource, or delete it and all of its child resources. Objects
 * of this type should be instantiated via
 * {@link ResourceOrganizer#resource(java.net.URI)}.
 * 
 * @author Alex Horn
 * @param <E> class type of resource representation
 * @see ResourceOrganizer#resource(java.net.URI)
 */
public interface ResourceController<E> {

  /**
   * Obtain the URI with which this {@link ResourceController} is associated.
   * 
   * @return uniform resource identifier of this resource controller
   */
  public java.net.URI uri();

  /**
   * Dereference the parent resource controller. The return value is {@code
   * null} if the {@link #uri() URI} is opaque or if its path is the root.
   * 
   * @return parent resource controller or {@code null} if there is none
   */
  public ResourceController<E> parent();

  /**
   * Obtain the resource representation of type {@code <E>} that is managed by
   * this resource controller. The return value is {@code null} if the resource
   * does not exist or it has no representation.
   * 
   * @return resource representation or {@code null} if there is none
   */
  public E get();

  /**
   * Save the provided representation to the underlying data structure
   * maintained by the service provider. The representation object must be
   * thread-safe if the {@link ResourceOrganizer} is shared by multiple
   * processes or threads.
   * 
   * @param representation non-null object that represents the content
   *          associated with the {@link #uri() resource URI}
   * @throws IllegalArgumentException if the representation argument is {@code
   *           null}
   * @return previous resource representation associated with {@link #uri() URI}
   *         or {@code null} if there has been no existing representation
   *         overridden
   */
  public E put(E representation);

  /**
   * Remove this resource and all of its child resources.
   * 
   * @return an unmodifiable set of URIs for resources that were deleted, or an
   *         empty set if no resource was removed
   */
  public Set<java.net.URI> delete();

  /**
   * Compare two {@link ResourceController} objects for equality. They are equal
   * if their {@link #uri() URIs} are {@link java.net.URI#equals(Object) equal}.
   * 
   * @param object object that should be compared for equality
   * @return boolean {@code true} if both {@link ResourceController#uri()}
   *         match, {@code false} if the resource controllers are responsible
   *         for different URIs
   */
  public boolean equals(Object object);

  /**
   * Compute the hash code of a {@link ResourceController} from its
   * {@link #uri() URI}.
   * 
   * @return hash code of the resource controller
   */
  public int hashCode();

  /**
   * Get a debugger-friendly representation of this {@link ResourceController}
   * 
   * @return lexical representation of the {@link #uri() URI}
   */
  public String toString();
}
